using System;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections.Specialized;
using My.IdlConverter.Core;
using My.IdlConverter.Core.Util;
using My.IdlConverter.Core.Output;
using My.IdlConverter.Core.Parsers;
using My.IdlConverter.Core.Producers;
using My.IdlConverter.Core.Cfg;

namespace My.IdlConverter.Com
{
    public class ComClassExport : ExportBase
    {
        private StringCollection _filesCache = new StringCollection();

        public ComClassExport(string targetFolder)
            : base(targetFolder)
        {
        }

        public override void Export()
        {
            IOHelper.PathNameFilterFun filter = new IOHelper.PathNameFilterFun(Delegators.FilterClassFileFunc);
            StringCollection files = IOHelper.GetCppHeaderFiles(Configuration.ClassFolder, filter, false);

            IParser classParser = new ClassParser();
            Class classObj = null;
            string fileName = null;
            ExportEventArgs args = new ExportEventArgs();
            foreach (string nextFile in files)
            {
                Trace.WriteLine(nextFile);

                classParser.OverloadCollision = MethodCollisionManager.Instance.GetCollision<ComOverloadMethodCollision>();
                classObj = classParser.Parse(nextFile) as Class;
                if (classObj != null)
                {
                    fileName = Path.GetFileNameWithoutExtension(nextFile);
                    fileName = fileName.Trim().Remove(0, "DOM".Length);
                    _filesCache.Add(fileName + ".h");

                    ExportHeaderFile(classObj, Path.Combine(TargetPath, fileName + ".h"));
                    ExportCppFile(classObj, Path.Combine(TargetPath, fileName + ".cpp"));
                }

                args.FileName = nextFile;
                FireExportEvent(args);
            }

            //ModifyDefsFile(Path.Combine(TargetPath, "defs.h"));
        }

        protected virtual void ExportHeaderFile(Class classObj,string tartgetPathName)
        {
            IStreamWriter<String> writer = new TextStreamWriter<String>("");

            IProducer<Class> classProducer = new ComClassHeaderFileProducer();
            classProducer.Consumer = classObj;
            writer.Path = tartgetPathName;
            string headerFile = classProducer.Produce();
            writer.Write(headerFile);
        }

        protected virtual void ExportCppFile(Class classObj, string tartgetPathName)
        {
            IStreamWriter<String> writer = new TextStreamWriter<String>("");

            IProducer<Class> classProducer = new ComClassCppFileProducer();
            classProducer.Consumer = classObj;
            writer.Path = tartgetPathName;

            string cppFile = classProducer.Produce();
            writer.Write(cppFile);
        }

        private void ModifyDefsFile(string defsFileName)
        {
            StringBuilder sb = new StringBuilder();

            foreach (string nextFile in _filesCache)
            {
                sb.AppendLine(String.Format("#include \"{0}\"",nextFile));
            }

            IStreamWriter<string> writer = new TextStreamWriter<string>(defsFileName);
            writer.Append(sb.ToString());
        }
    }
}
